#include "CMySkt.h"

VOID CMySkt::Init()
{
    static BOOL isInit = FALSE;
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);
    isInit = TRUE;
    return VOID();
}

SOCKET CMySkt::CreatTcpSocket()
{
    SOCKET servSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    return servSock;
}

VOID CMySkt::Bind(SOCKET& servSock, char ip[], u_short port)
{
    sockaddr_in sockAddr;    
    memset(&sockAddr, 0, sizeof(sockAddr));  
    sockAddr.sin_family = PF_INET; 
    sockAddr.sin_addr.s_addr = inet_addr(ip);  
    sockAddr.sin_port = htons(port);
    bind(servSock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR));
    return VOID();
}

VOID CMySkt::Bind(SOCKET& servSock, sockaddr_in& addr)
{

    bind(servSock, (SOCKADDR*)&addr, sizeof(SOCKADDR));
    return VOID();
}

SOCKET CMySkt::Listen(char ip[], u_short port, DWORD backlog)
{

    SOCKET servSock = INVALID_SOCKET;
    CMySkt::Init();
    servSock = CreatTcpSocket();
    if (INVALID_SOCKET != servSock) 
    {
        Bind(servSock, ip, port);
        if (0 != listen(servSock, backlog)) 
        {
            servSock = INVALID_SOCKET;
        }
    }
    return servSock;
}

SOCKET CMySkt::Accept(SOCKET& servSock, sockaddr_in &clntAddr)
{
    SOCKET clntSock = INVALID_SOCKET;
    int nSize = 0;
    if (INVALID_SOCKET != servSock) 
    {
        nSize = sizeof(SOCKADDR);
        clntSock = accept(servSock, (SOCKADDR*)&clntAddr, &nSize);
    }
    return clntSock;
}

SOCKET CMySkt::Connect(OUT SOCKET &sock, char ip[], u_short port)
{

    sock = INVALID_SOCKET;
    CMySkt::Init();
    sock = CreatTcpSocket();
    if (INVALID_SOCKET != sock)
    {
        sockaddr_in sockAddr;    
        memset(&sockAddr, 0, sizeof(sockAddr));
        sockAddr.sin_family = PF_INET;    
        sockAddr.sin_addr.s_addr = inet_addr(ip);
        sockAddr.sin_port = htons(port);
        if (0 != connect(sock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR))) 
        {
            sock = INVALID_SOCKET;
        }
    }
    return sock;
}

BOOL CMySkt::Send(SOCKET& sock, LPVOID data, UINT dataSize)
{
    BOOL ret = FALSE;
    if (INVALID_SOCKET != sock)
    {
        if ((NULL != data) && (dataSize > 0))
        {
            UINT sended = 0;
            while ( sended < dataSize)
            {
                int nSend = send(sock, (const char *)data, dataSize, NULL);
                if (SOCKET_ERROR == nSend)
                {
                    return FALSE;
                }
                sended += nSend;
            }
            ret = TRUE;
        }
    }
    return ret;
}

BOOL CMySkt::RecvAll(SOCKET& sock, LPVOID data, UINT dataSize)
{
    BOOL ret = FALSE;
    if (INVALID_SOCKET != sock)
    {
        if ((NULL != data) && (dataSize > 0)) 
        {
            UINT recved = 0;
            while (recved < dataSize)
            {
                int nRecv = recv(sock, (char*)data, dataSize, NULL);
                if (SOCKET_ERROR == nRecv)
                {
                    return FALSE;
                }
                recved += nRecv;
            }
            ret = TRUE;
        }
    }
    return ret;
}

BOOL CMySkt::Recv(SOCKET& sock, LPVOID data, IN OUT UINT& dataSize)
{
    BOOL ret = FALSE;
    if (INVALID_SOCKET != sock)
    {
        if ((NULL != data) && (dataSize > 0))
        {
            int nRecv = recv(sock, (char*)data, dataSize, NULL);
            if (SOCKET_ERROR != nRecv)
            {
                dataSize = nRecv;
                ret = TRUE;
            }
        }
    }
    return ret;
}

VOID CMySkt::Clean()
{
    WSACleanup();
    return VOID();
}
